import java.util.ArrayList;

public class Tester extends TestToolBox {

	private Sorter[] sorter;
	private ArrayList<int[]> arraysToBeSorted;
	private int[] stepArray;

	public Tester(int first, int last, int reps, int steps, Sorter[] sorter) {
		super(first, last, reps, steps);
		this.sorter = sorter;
	}

	public double[][] startTesting() {
		double[][] sortingTimes;
		sortingTimes = new double[sorter.length][steps];
		stepArray = makeStepArray();
		makeStepIntervalArray();
		for (int j = 0; j < sorter.length; j++) {

			sortingTimes[j] = test(sorter[j]);
		}
		return sortingTimes;
	}

	public int[] getStepArray() {
		return stepArray;
	}

	private void makeStepIntervalArray() {
		arraysToBeSorted = new ArrayList<int[]>();
		for (int i = 1; i <= steps; i++) {
			arraysToBeSorted.add(randomizeArray(populateArray(stepArray[0],
					stepArray[i])));
		}
	}

	private double[] test(Sorter sort) {
		double starttime;
		double[][] finishTimes = new double[reps][steps + 1];
		int[] arrayCopy;

		for (int i = 0; i < reps; i++) {
			for (int j = 0; j < steps; j++) {
				arrayCopy = new int[arraysToBeSorted.get(j).length];
				System.arraycopy(arraysToBeSorted.get(j), 0, arrayCopy, 0,
						arraysToBeSorted.get(j).length);
				System.gc();
				starttime = System.nanoTime();

				sort.sort(arrayCopy, arrayCopy.length - 1);
				finishTimes[i][j] = System.nanoTime() - starttime;

			}
		}
		return calculateAverageRunTime(finishTimes);
	}

	private double[] calculateAverageRunTime(double[][] finishTimes) {
		double[] runTimes = new double[steps + 1];
		for (int i = 0; i < steps; i++) {
			for (int j = 0; j < reps; j++) {
				runTimes[i] = runTimes[i] + finishTimes[j][i];
			}

			// Creating average and converting to microseconds
			runTimes[i] = runTimes[i] / reps / 1000;

		}
		return runTimes;
	}

}